package com.hollycrm.unicom.lockservice.memory;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.hollycrm.springframework.factory.DefaultBeanFactory;
import com.hollycrm.springframework.util.StringUtils;
import com.hollycrm.unicom.lockservice.LockManager;
import com.hollycrm.unicom.lockservice.LockObject;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author Tian Kai
 * @version 1.0
 */

public class MemoryLockManager implements LockManager {

    Map memoryLocks = Collections.synchronizedMap(new HashMap());

    public MemoryLockManager() {
    }

    /**
     * lock
     *
     * @param lockID String
     * @param locker String
     * @return boolean
     */
    public boolean lock(String lockID, String locker) {
        LockObject lockObject = (LockObject) memoryLocks.get(lockID);

        if (lockObject != null &&
            StringUtils.equals(locker, lockObject.getLocker()))
            return true;

        if (lockObject == null || !lockObject.isValid()) {
            memoryLocks.put(lockID, buildLockObject(lockID, locker));
            return true;
        }

        return false;
    }

    /**
     * unlock
     *
     * @param lockID String
     * @param locker String
     * @return boolean
     */
    public boolean unlock(String lockID, String locker) {
        LockObject lockObject = (LockObject) memoryLocks.get(lockID);

        if (lockObject != null &&
            StringUtils.equals(locker, lockObject.getLocker())) {
            memoryLocks.remove(lockID);
            return true;
        }else if(lockObject == null)
        {
            return true;
        }
        return false;
    }

    /**
     * forceLock
     *
     * @param lockID String
     * @param locker String
     * @return boolean
     */
    public boolean forceLock(String lockID, String locker) {
        memoryLocks.put(lockID, buildLockObject(lockID, locker));
        return true;
    }

    /**
     * checkLockValid
     *
     * @param lockID String
     * @return boolean
     */
    public boolean checkLockValid(String lockID) {
        LockObject lockObject = (LockObject) memoryLocks.get(lockID);
        return lockObject != null && lockObject.isValid();
    }

    /**
     * getLocker
     *
     * @param lockID String
     * @return String
     */
    public String getLocker(String lockID) {
        LockObject lockObject = (LockObject) memoryLocks.get(lockID);
        return lockObject != null ? lockObject.getLocker() : "UNKNOW LOCKER";
    }

    /**
     * buildLockObject
     *
     * @param lockID String
     * @param locker String
     * @return LockObject
     */
    private LockObject buildLockObject(String lockID, String locker) {
        LockObject lockObject = (LockObject) DefaultBeanFactory.getBean(
            "lockTemplate");
        lockObject.setLockID(lockID);
        lockObject.setLocker(locker);
        lockObject.setLockTimeMillis(System.currentTimeMillis());
        return lockObject;
    }

}
